﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace ShakeIt_Server
{
    public class Service1 : IService1
    {
        public int Login(string username, string password)
        {
            List<User> result = new List<User>();
            result = FindUserByName(username);
            if (result.Count != 0)
            {
                if (result[0].password == password)
                {
                    return result[0].id;
                }
                return -1;
            }
            else
            {
                return -1;
            }
        }

        public List<_User> FindUser(int userid)
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            var res = from r in context.User where r.id == userid select r;
            List<_User> result = new List<_User>();
            foreach(User user in res.ToList())
            {
                result.Add(new _User(user));
            }
            return result;
        }

        public List<User> FindUserByName(string username)
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            var res = from r in context.User where r.username == username select r;
            return res.ToList();
        }

        public string InsertUser(string username, string password, string cellPhone)
        {
            User user = new User();
            user.username = username;
            user.password = password;
            user.cellPhone = cellPhone;
            Console.WriteLine("-----begin Add a user");
            DataClasses1DataContext context = new DataClasses1DataContext();
            var exist_user = from r in context.User where r.username == user.username select r;
            if (exist_user.Count() > 0) //如果该用户名已经存在，返回插入失败信息
            {
                return "该用户名已经存在";
            }
            try
            {
                var alluser = from r in context.User select r;
                user.id = alluser.Count();
                context.Log = Console.Out;
                context.User.InsertOnSubmit(user);
                context.SubmitChanges();
                return "注册成功";
            }
            catch{
                return "服务器发生错误";
            }
        }

        public string UpdatePassword(string username, string old_password, string new_password) 
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            //取出User
            var editUser = context.User.SingleOrDefault<User>(u => u.username == username);
            if (editUser == null)
            {
                return "该用户不存在";
            }
            if (!editUser.password.Trim().Equals(old_password)) //Trim方法取出字符串后面的空格符
            {
                return "旧密码输入错误";
            }
            //修改User的密码
            editUser.password = new_password;
            //执行更新操作
            context.SubmitChanges();
            return "修改成功";
        }

        public string UpdateCellPhone(string username, string cellPhone)
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            //取出User
            var editUser = context.User.SingleOrDefault<User>(u => u.username == username);
            if (editUser == null)
            {
                return "该用户不存在";
            }
            //修改User的手机号码
            editUser.cellPhone = cellPhone;
            //执行更新操作
            context.SubmitChanges();
            return "修改成功";
        }
        
        public List<_Activity> FindActivityById(int id)
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            var res = from r in context.Activity where r.id == id select r;
            List<_Activity> result = new List<_Activity>();
            foreach (Activity acti in res)
            {
                result.Add(new _Activity(acti));
            }
            return result;
        }

        public List<_Activity> FindActivityByLocation(decimal currentLongitude, decimal currentLatitude)
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            var res = from r in context.Activity select r;
            List<_Activity> result = new List<_Activity>();
            foreach (Activity acti in res)
            {
                GaussSphere gs = GaussSphere.Beijing54;
                double distance = DistanceOfTwoPoints((double)acti.longitude, (double)acti.latitude, (double)currentLongitude, (double)currentLatitude, gs);
                DateTime now = DateTime.Now;
                if (acti.endTime > now && distance < 2000)
                {
                    result.Add(new _Activity(acti, distance));
                }
            }
            return result;
        }

        public List<_Activity> FindActivityByLocationAndKeyword(decimal currentLongitude, decimal currentLatitude, string keyword)
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            var res = from r in context.Activity where r.title.Contains(keyword) select r;
            List<_Activity> result = new List<_Activity>();
            foreach (Activity acti in res)
            {
                GaussSphere gs = GaussSphere.Beijing54;
                double distance = DistanceOfTwoPoints((double)acti.longitude, (double)acti.latitude, (double)currentLongitude, (double)currentLatitude, gs);
                DateTime now = DateTime.Now;
                if (acti.endTime > now && distance < 5000)
                {
                    result.Add(new _Activity(acti, distance));
                }
            }
            return result;
        }

        public static double DistanceOfTwoPoints(double lng1,double lat1, double lng2, double lat2, GaussSphere gs)
        {            
            double radLat1 = Rad(lat1);
            double radLat2 = Rad(lat2);
            double a = radLat1 - radLat2;
            double b = Rad(lng1) - Rad(lng2);
            double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) +
             Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2)));

            s = s * (gs == GaussSphere.WGS84 ? 6378137.0 : (gs == GaussSphere.Xian80 ? 6378140.0 : 6378245.0));
            s = Math.Round(s * 10000) / 10000;
            return s;
        }
        
        private static double Rad(double d)
        {
            return d * Math.PI / 180.0;
        }
        //GaussSphere 为自定义枚举类型
        /// <summary>
        /// 高斯投影中所选用的参考椭球
        /// </summary>
        public enum GaussSphere
        {
            Beijing54,
            Xian80,
            WGS84,
        }

        public string InsertActivity(int userid, string type, string title, string detail, decimal longitude, decimal latitude, string address, DateTime beginTime, DateTime endTime)
        {
            Activity activity = new Activity();
            activity.userId = userid;
            activity.type = type;
            activity.title = title;
            activity.detail = detail;
            activity.longitude = longitude;
            activity.latitude = latitude;
            activity.address = address;
            activity.beginTime = beginTime;
            activity.endTime = endTime;
            Console.WriteLine("-----begin Add a activity");
            DataClasses1DataContext context = new DataClasses1DataContext();
            try
            {
                var allActivity = from r in context.Activity select r;
                activity.id = allActivity.Count();
                context.Log = Console.Out;
                context.Activity.InsertOnSubmit(activity);
                context.SubmitChanges();
                return "成功添加活动";
            }
            catch
            {
                return "服务器发生错误";
            }
        }

        public string UpdateActivity(int id, string type, string title, string detail, decimal longitude, decimal latitude, string address, DateTime beginTime, DateTime endTime)
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            //取出Activity
            var editActivity = context.Activity.SingleOrDefault<Activity>(a => a.id == id);
            if (editActivity == null)
            {
                return "该活动不存在";
            }
            //修改Activitiy
            editActivity.type = type;
            editActivity.title = title;
            editActivity.detail = detail;
            editActivity.longitude = longitude;
            editActivity.latitude = latitude;
            editActivity.address = address;
            editActivity.beginTime = beginTime;
            editActivity.endTime = endTime;
            //执行更新操作
            context.SubmitChanges();
            return "修改成功";
        }

        public List<_UserComment> GetAllComment(int userId) 
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            var res = from r in context.UserComment where r.userId == userId select r;
            List<_UserComment> result = new List<_UserComment>();
            foreach (UserComment uc in res)
            {
                result.Add(new _UserComment(uc));
            }
            return result;
        }

        /*public List<_UserComment> GetRecentComment(int userId)
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            var res = from r in context.UserComment where r.userId == userId select r;
            List<_UserComment> result = new List<_UserComment>();
            UserComment recentUc = res.ToList()[0];
            foreach (UserComment uc in res)
            {
                if (uc.id > recentUc.id)
                {
                    recentUc = uc;
                }
            }
            result.Add(new _UserComment(recentUc));
            return result;
        }*/

        public string InsertComment(int userId, int commenterId, int score, string commentContent)
        {
            UserComment uc = new UserComment();
            uc.userId = userId;
            uc.commenterId = commenterId;
            uc.score = score;
            uc.commentContent = commentContent;
            uc.time = DateTime.Now;
            Console.WriteLine("-----begin Add a comment");
            DataClasses1DataContext context = new DataClasses1DataContext();
            try
            {
                var allComment = from r in context.UserComment select r;
                uc.id = allComment.Count();
                context.Log = Console.Out;
                context.UserComment.InsertOnSubmit(uc);
                context.SubmitChanges();
                return "成功添加评论";
            }
            catch
            {
                return "服务器发生错误";
            }
        }

        /*public double GetScore(int userId)
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            var res = from r in context.UserComment where r.userId == userId select r;
            double count = 0;
            double sum = 0;
            foreach (UserComment uc in res)
            {
                sum += uc.score;
                count++;
            }
            return Math.Round(sum / count , 2);
        }*/

        public string SetFocus(int id1, int id2)
        {
            Focus fs = new Focus();
            fs.mainId = id1;
            fs.fanId = id2;
            Console.WriteLine("-----begin Add a Focus");
            DataClasses1DataContext context = new DataClasses1DataContext();
            try
            {
                context.Log = Console.Out;
                context.Focus.InsertOnSubmit(fs);
                context.SubmitChanges();
                return "成功添加关注";
            }
            catch
            {
                return "服务器发生错误";
            }
        }

        public string RemoveFocus(int id1, int id2)
        {
            Console.WriteLine("-----begin Remove a Focus");
            DataClasses1DataContext context = new DataClasses1DataContext();
            try
            {
                var editFocus = context.Focus.SingleOrDefault<Focus>(f => f.mainId == id1 && f.fanId == id2);
                context.Log = Console.Out;
                context.Focus.DeleteOnSubmit(editFocus);
                context.SubmitChanges();
                return "成功移除关注";
            }
            catch
            {
                return "服务器发生错误";
            }
        }

        public List<_User> GetFans(int id)
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            var res = from r in context.Focus where r.mainId == id select r.User1;
            List<_User> result = new List<_User>();
            foreach (User user in res.ToList())
            {
                result.Add(new _User(user));
            }
            return result;
        }

        public List<_User> GetFocus(int id)
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            var res = from r in context.Focus where r.fanId == id select r.User;
            List<_User> result = new List<_User>();
            foreach (User user in res.ToList())
            {
                result.Add(new _User(user));
            }
            return result;
        }

        public bool IsFocus(int id1, int id2)
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            var res = from r in context.Focus where r.mainId == id1 & r.fanId == id2 select r.User.username;
            if (res.ToList().Count == 0) return false;
            else return true;
        }
        
        public List<_Chat> FindChatBySendId(int sendId)
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            var res = from r in context.Chat where r.sendId == sendId select r;
            List<_Chat> result = new List<_Chat>();
            foreach (Chat c in res)
            { 
                result.Add(new _Chat(c));
            }
            return result;
        }

        public List<_Chat> FindChatByReceiveId(int receiveId)
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            var res = from r in context.Chat where r.receiveId == receiveId & r.arrive == false select r;
            List<_Chat> result = new List<_Chat>();
            foreach (Chat c in res)
            {
                var editChat = context.Chat.SingleOrDefault<Chat>(ec => ec.id == c.id);
                editChat.arrive = true;
                result.Add(new _Chat(c));
                context.SubmitChanges();
            }
            return result;
        }

        public List<_Chat> FindAllChatBetweenTwo(int id1, int id2)
        {
            DataClasses1DataContext context = new DataClasses1DataContext();
            var res1 = from r in context.Chat where r.sendId == id1 select r;
            var res2 = from r in context.Chat where r.sendId == id2 select r;
            List<Chat> chatlist1 = res1.ToList();
            List<Chat> chatlist2 = res2.ToList();
            chatlist1.AddRange(chatlist2);
            List<_Chat> result = new List<_Chat>();
            foreach (Chat c in chatlist1)
            {
                result.Add(new _Chat(c));
            }
            return result;
        }

        public string InsertChat(string content, int sendId, int receiveId)
        {
            Chat chat = new Chat();
            chat.chatContent = content;
            chat.sendId = sendId;
            chat.receiveId = receiveId;
            chat.sendTime = DateTime.Now;
            Console.WriteLine("-----begin Add a chat content");
            DataClasses1DataContext context = new DataClasses1DataContext();
            try
            {
                var allChat = from r in context.Chat select r;
                chat.id = allChat.Count();
                context.Log = Console.Out;
                context.Chat.InsertOnSubmit(chat);
                context.SubmitChanges();
                return "成功添加聊天记录";
            }
            catch
            {
                return "服务器发生错误";
            }
        }
    }
}
